﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using GDI测试.Properties;


namespace GDI测试
{
    public partial class GdiControl : UserControl
    {
        Resources r = new Resources();

        Bitmap backBuffer = null;
        Graphics gxOff = null;

        SZGrid[,] rects = null;
        Pen p = new Pen(Brushes.White, 1);

        //  底部格子数
        int xcount = 0;
        int ycount = 0;

        object[,] feedlist = null;

        List<SZGrid> body = new List<SZGrid>(5);

        /// <summary>
        /// 上下左右
        /// </summary>
        public Keys GoKeys { get; set; }

        public Image bgimgfile { get; set; }

        public GdiControl()
        {
            string[] bg = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "bg");
            Image[] aa = new Image[bg.Length];
            for (int i = 0; i < bg.Length; i++)
            {
                aa[i] = Bitmap.FromFile(bg[i]);
                aa[i] = new Bitmap(aa[i], 800, 600);
            }

            this.bgimgfile = aa[new Random().Next(0, bg.Length - 1)];

            InitializeComponent();

            this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
            this.UpdateStyles();

           
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (gxOff != null && backBuffer != null)
            {
                gxOff.Clear(Color.Tomato);
                gxOff.DrawImage(bgimgfile, 0, 0);
            }

            ShowGridLines(gxOff);

            e.Graphics.DrawImage(backBuffer, 0, 0);
        }

        private void ShowGridLines(Graphics g)
        {
            for (int i = 0; i < xcount; i++)
            {
                for (int j = 0; j < ycount; j++)
                {
                    if (feedlist[i, j] == null)
                    {
                        g.FillRectangle(rects[i, j].BgColor, rects[i, j].LocalArea);
                    }
                    g.DrawRectangle(p, rects[i, j].LocalArea);
                    if (rects[i, j].BgImg != null)
                    {
                        g.DrawImage(rects[i, j].BgImg, rects[i, j].LocalArea);
                    }
                }
            }
            for (int i = 0; i < body.Count; i++)
            {
                g.FillRectangle(body[i].BgColor, body[i].LocalArea);
                if (body[i].BgImg != null)
                {
                    g.DrawImage(body[i].BgImg, body[i].LocalArea);
                }
                g.DrawRectangle(new Pen(Brushes.MistyRose,1.0f), body[i].LocalArea);

            }// end foreach
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            if (backBuffer != null)
            {
                backBuffer.Dispose();
                backBuffer = null;
            }
            if (gxOff != null)
            {
                gxOff.Dispose();
                gxOff = null;
            }
            if (Width < 100 || Height < 100)
                return;

            if (this.bgimgfile != null)
            {
               
            }

            backBuffer = new Bitmap(this.bgimgfile);
            gxOff = Graphics.FromImage(backBuffer);
        }

        Point mousePoint;
        private void GdiControl_MouseMove(object sender, MouseEventArgs e)
        {
            mousePoint = e.Location;
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (this.rects != null && mousePoint != null)
            {
                for (int i = 0; i < xcount; i++)
                {
                    for (int j = 0; j < ycount; j++)
                    {
                        rects[i, j].BgColor = Brushes.WhiteSmoke;
                        if (rects[i, j].LocalArea.Contains(mousePoint))
                        {
                            rects[i, j].BgColor = Brushes.OrangeRed;
                            this.Invalidate();
                        }
                    }
                }// end foreach

                for (int i = 0; i < body.Count; i++)
                {
                    body[i].BgColor = Brushes.Plum;
                }// end foreach

            }
            timer1.Stop();
        }

        private void timerGo_Tick(object sender, EventArgs e)
        {
            if (挂上)
            {
                int x = xx.X / Class1.GridSize.Width;
                int y = xx.Y / Class1.GridSize.Height;

                body.Insert(0, new SZGrid()
                {
                    BgColor = Brushes.PaleGreen,
                    Location = xx,
                    LocalArea = new Rectangle(xx, Class1.GridSize),
                    CurrentKey = aaa,
                    BgImg = rects[x, y].BgImg,
                });

                rects[x, y].BgImg = null;
                挂上 = false;
            }

            body[body.Count - 1].CurrentKey = GoKeys;
            BodyMove(body.Count - 1);

            for (int i = 0; i < body.Count - 1; i++)
            {
                BodyMove(i);
                body[i].CurrentKey = body[i + 1].CurrentKey;
            }

            //bool isdie = false;
            //for (int i = 1; i < body.Count; i++)
            //{
            //    if (body[i].Location.X == body[0].Location.X &&
            //        body[i].Location.Y == body[0].Location.Y)
            //    {
            //        isdie = true;
            //        break;
            //    }
            //}
            //if (isdie)
            //{
            //    for (int i = 0; i < body.Count; i++)
            //    {
            //        body[i].BgColor = Brushes.Red;
            //        body[i].BgImg = null;
            //        this.timerGo.Stop();
            //    }
            //}
            this.Invalidate();
        }

        Point xx = new Point();
        bool 挂上 = false;
        Keys aaa = Keys.A;
        private void BodyMove(int i)
        {
            int x = body[i].Location.X / Class1.GridSize.Width;
            int y = body[i].Location.Y / Class1.GridSize.Height;
            if (x >= xcount-1 || y >= ycount-1)
                return;
            if (x < 0 || y <0)
                return;

            if (rects[x, y].BgImg != null && i == 0 && !挂上)
            {
                挂上 = true;
                xx = body[i].Location;
             
                aaa = body[i].CurrentKey;
            }

            if (rects[x, y].BgImg != null && i == body.Count-1 && !挂上)
            {
                NewFeed();
            }

            switch (body[i].CurrentKey)
            {
                case Keys.Up:
                    body[i].Location = new Point(body[i].Location.X, body[i].Location.Y - Class1.GridSize.Height);
                    break;
                case Keys.Down:
                    body[i].Location = new Point(body[i].Location.X, body[i].Location.Y + Class1.GridSize.Height);
                    break;
                case Keys.Left:
                    body[i].Location = new Point(body[i].Location.X - Class1.GridSize.Width, body[i].Location.Y);
                    break;
                case Keys.Right:
                    body[i].Location = new Point(body[i].Location.X + Class1.GridSize.Width, body[i].Location.Y);
                    break;
            }
            body[i].LocalArea = new Rectangle(body[i].Location, Class1.GridSize);
              
        }

        internal void Start()
        {
            初始化底格();

            for (int i = 0; i < 5; i++)
            {
                SZGrid a = new SZGrid();
                a.BgColor = Brushes.PaleGreen;
                a.Location = new Point(i * Class1.GridSize.Width, 0);
                a.LocalArea = new Rectangle(a.Location, Class1.GridSize);
                a.CurrentKey = this.GoKeys;
                a.BgImg = imageList1.Images[i];
                body.Add(a);
            }

            NewFeed();

            this.Invalidate();

        }

        private void NewFeed()
        {
            Random r = new Random((int)(DateTime.Now.Ticks & 0x7FFFFFFF));


            int x = r.Next(0, xcount - 2);
            int y = r.Next(0, ycount - 2);

        //aasd:
        //    {
        //        foreach (SZGrid s in body)
        //        {
        //            if (s.Location.X == x && s.Location.Y == y)
        //            {
        //                x = r.Next(0, xcount - 2);
        //                y = r.Next(0, ycount - 2);
        //                goto aasd;
        //            }
        //        }
        //    }

            if (feedlist != null)
            {
                feedlist[x, y] = new object();
            }
            this.rects[x, y].BgImg = imageList1.Images[r.Next(0, imageList1.Images.Count - 1)];
        }

        private void 初始化底格()
        {
            xcount = this.Width / Class1.GridSize.Width + 1;
            ycount = this.Height / Class1.GridSize.Height + 1;

            rects = new SZGrid[xcount, ycount];

            for (int i = 0; i < xcount; i++)
            {
                for (int j = 0; j < ycount; j++)
                {
                    rects[i, j] = new SZGrid()
                    {
                        BgColor = Brushes.WhiteSmoke,
                        Location = new Point(i * Class1.GridSize.Width, j * Class1.GridSize.Height),
                        LocalArea = new Rectangle(i * Class1.GridSize.Width, j * Class1.GridSize.Height, Class1.GridSize.Width, Class1.GridSize.Height)
                    };
                }
            }

            this.feedlist = new object[xcount, ycount];

       
        }

        private void GdiControl_Load(object sender, EventArgs e)
        {
            GoKeys = Keys.Right;
            timerGo.Start();

            string[] files =  Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "body");
            foreach (string s in files)
            {
                this.imageList1.Images.Add(Bitmap.FromFile(s));
            }

         
         
        }

        private void GdiControl_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            timerGo.Stop();
            this.GoKeys = e.KeyCode;
            timerGo_Tick(null, null);

            timerGo.Start();
        }


     
    }
}